package com.foodorder.entity;

import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 订单实体类
 */
@Data
@Entity
@Table(name = "orders")
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Order {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    /**
     * 订单号
     */
    @Column(nullable = false, unique = true)
    private String orderNo;
    
    /**
     * 用户ID
     */
    @Column(nullable = false)
    private Long userId;
    
    /**
     * 店铺ID
     */
    @Column(nullable = false)
    private Long storeId;
    
    /**
     * 订单状态
     */
    @Column(nullable = false)
    @Enumerated(EnumType.STRING)
    private OrderStatus status;
    
    /**
     * 订单类型
     */
    @Column(nullable = false)
    @Enumerated(EnumType.STRING)
    private OrderType type = OrderType.DELIVERY;
    
    /**
     * 商品总金额
     */
    @Column(nullable = false, precision = 10, scale = 2)
    private BigDecimal productAmount;
    
    /**
     * 配送费
     */
    @Column(nullable = false, precision = 10, scale = 2)
    private BigDecimal deliveryFee;
    
    /**
     * 优惠金额
     */
    @Column(precision = 10, scale = 2)
    private BigDecimal discountAmount;
    
    /**
     * 实付金额
     */
    @Column(nullable = false, precision = 10, scale = 2)
    private BigDecimal totalAmount;
    
    /**
     * 收货地址（JSON格式）
     */
    private String deliveryAddress;
    
    /**
     * 收货人姓名
     */
    private String receiverName;
    
    /**
     * 收货人电话
     */
    private String receiverPhone;
    
    /**
     * 预计送达时间
     */
    private LocalDateTime estimatedDeliveryTime;
    
    /**
     * 实际送达时间
     */
    private LocalDateTime actualDeliveryTime;
    
    /**
     * 订单备注
     */
    private String remark;
    
    /**
     * 支付方式
     */
    private String paymentMethod;
    
    /**
     * 支付交易ID
     */
    private String paymentTransactionId;
    
    /**
     * 支付时间
     */
    private LocalDateTime paidAt;
    
    /**
     * 完成时间
     */
    private LocalDateTime completedAt;
    
    /**
     * 取消时间
     */
    private LocalDateTime cancelledAt;
    
    /**
     * 取消原因
     */
    private String cancelReason;
    
    /**
     * 创建时间
     */
    @CreationTimestamp
    private LocalDateTime createdAt;
    
    /**
     * 更新时间
     */
    @UpdateTimestamp
    private LocalDateTime updatedAt;
    
    /**
     * 订单商品明细
     */
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "order_id")
    private List<OrderItem> orderItems = new ArrayList<>();
    
    /**
     * 获取订单类型
     */
    public OrderType getType() {
        return this.type;
    }
    
    /**
     * 订单状态枚举
     */
    public enum OrderStatus {
        /**
         * 待支付
         */
        PENDING_PAYMENT,
        
        /**
         * 已支付
         */
        PAID,
        
        /**
         * 准备中（商家接单后）
         */
        PREPARING,
        
        /**
         * 处理中（商家接单后）
         */
        PROCESSING,
        
        /**
         * 配送中
         */
        DELIVERING,
        
        /**
         * 已完成
         */
        COMPLETED,
        
        /**
         * 已取消
         */
        CANCELLED,
        
        /**
         * 已退款
         */
        REFUNDED
    }
    
    /**
     * 订单类型枚举
     */
    public enum OrderType {
        /**
         * 外卖配送
         */
        DELIVERY,
        
        /**
         * 到店自取
         */
        PICKUP,
        
        /**
         * 堂食
         */
        DINE_IN
    }
    
    /**
     * 添加订单项
     */
    public void addOrderItem(OrderItem orderItem) {
        orderItems.add(orderItem);
    }
    
    /**
     * 计算商品总价
     */
    public BigDecimal calculateProductAmount() {
        return orderItems.stream()
                .map(OrderItem::getSubtotal)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }
    
    /**
     * 计算订单总价
     */
    public BigDecimal calculateTotalAmount() {
        BigDecimal productTotal = calculateProductAmount();
        BigDecimal delivery = this.deliveryFee != null ? this.deliveryFee : BigDecimal.ZERO;
        BigDecimal discount = this.discountAmount != null ? this.discountAmount : BigDecimal.ZERO;
        
        return productTotal.add(delivery).subtract(discount);
    }
    
    /**
     * 确认订单金额
     */
    public void confirmAmounts() {
        this.productAmount = calculateProductAmount();
        this.totalAmount = calculateTotalAmount();
    }
} 